/**
 * Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yun.web.hotswap;

import yun.web.hotswap.hotswap.ClassLoaderKit;
import yun.web.hotswap.hotswap.HotSwapResolver;

/**
 * HotswapConfig
 */
public class HotswapConfig {

    protected String hookClass;

    protected String hotSwapClassPrefix = null;

    protected String[] classPathDirs;                // 存放 .class 文件的目录
    protected HotSwapResolver hotSwapResolver;
    protected ClassLoaderKit classLoaderKit;

    public HotswapConfig(String hookClass) {
        this.hookClass = hookClass;
    }

    /**
     * 假定用户创建 Hotswap 时指定 undertow 的配置文件为 abc.txt
     * 或者 abc-dev.txt 或者 abc_dev.txt，例如：
     * Hotswap.create(AppConfig.class, "abc.txt").start();
     * <p>
     * 尝试加载 abc-pro.txt 便于在 fatjar 模式下以 config 目录中通过创建
     * abc-pro.txt 配置文件覆盖打包在 jar 包中的 abc-dev.txt 配置
     */
    protected String buildUndertowConfigPro(String undertowConfig) {
        int index = undertowConfig.lastIndexOf('.');
        if (index > 0) {
            String main = undertowConfig.substring(0, index);
            main = removeDevEnds(main);
            String ext = undertowConfig.substring(index);
            return main + "-pro" + ext;
        } else {
            return removeDevEnds(undertowConfig) + "-pro";
        }
    }

    private String removeDevEnds(String main) {
        if (main.length() > 4) {
            if (main.endsWith("-dev")) {
                main = main.substring(0, main.lastIndexOf("-dev"));
            } else if (main.endsWith("_dev")) {
                main = main.substring(0, main.lastIndexOf("_dev"));
            }
        }
        return main;
    }


    public static boolean isBlank(String str) {
        return str == null || "".equals(str.trim());
    }

    public static boolean notBlank(String str) {
        return !isBlank(str);
    }


    protected ClassLoaderKit getClassLoaderKit() {
        if (classLoaderKit == null) {
            classLoaderKit = new ClassLoaderKit(HookItf.class.getClassLoader(), getHotSwapResolver());
        }
        return classLoaderKit;
    }

    public ClassLoader getClassLoader() {
        // return isDevMode() ? getClassLoaderKit().getClassLoader() : Undertow.class.getClassLoader();

        /**
         * 不论是否为 devMode 都使用 HotSwapClassLoader
         * HotSwapClassLoader 添加了 isDevMode() 判断
         * 一直使用 HotSwapClassLoader 是因为为其添加了
         * 配置文件 config 目录到 class path，以便可以加载
         * 外部配置文件
         */
        return getClassLoaderKit().getClassLoader();
    }

    public void replaceClassLoader() {
        if (isDevMode()) {
            getClassLoaderKit().replaceClassLoader();
        }
    }

    public HotSwapResolver getHotSwapResolver() {
        if (hotSwapResolver == null) {
            hotSwapResolver = new HotSwapResolver(getClassPathDirs());
            // 后续将此代码转移至 HotSwapResolver 中去，保持 HotswapConfig 的简洁
            if (hotSwapClassPrefix != null) {
                for (String prefix : hotSwapClassPrefix.split(",")) {
                    if (notBlank(prefix)) {
                        hotSwapResolver.addHotSwapClassPrefix(prefix);
                    }
                }
            }
        }
        return hotSwapResolver;
    }

    public void setHotSwapResolver(HotSwapResolver hotSwapResolver) {
        this.hotSwapResolver = hotSwapResolver;
    }

    public void addSystemClassPrefix(String prefix) {
        getHotSwapResolver().addSystemClassPrefix(prefix);
    }

    public void addHotSwapClassPrefix(String prefix) {
        getHotSwapResolver().addHotSwapClassPrefix(prefix);
    }

    /**
     * 获取存放 .class 文件的所有 classPath 目录，绝大部分场景下只有一个目录
     */
    public String[] getClassPathDirs() {
        if (classPathDirs == null) {
            classPathDirs = HotswapKit.getClassPathDirs();
        }
        return classPathDirs;
    }


    public static boolean isDevMode() {
        return System.getProperty("dev_mode") == null;
    }

}









